﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using MyWeb.WebUI.Tools;
using Castle.Windsor;
using Castle.MicroKernel.Registration;
using WebNext.Domain.Interfaces;
using Castle.MicroKernel.Context;
using WebNext.Domain.Entities;
using WebNext.UI.Utils;
using System.Threading;
using System.Globalization;
using log4net.Config;
using WebNext.UI.Models.Tags;
using WebNext.UI.Models.Comments;
using WebNext.UI.Utils.ModelBinders;
using WebNext.UI.Models.Login;
using WebNext.UI.Models.Admin;
using WebNext.UI.Models;
using WebNext.UI.Models.Entries;
using System.Configuration;
using WebNext.UI.Models.Contact;

namespace WebNext.UI
{
	public class MvcApplication : System.Web.HttpApplication
	{
		protected void Application_Start()
		{
			RuntimeSettings.SitePrefix = ConfigurationManager.AppSettings["SitePrefix"];
			RuntimeSettings.MetaAuthor = ConfigurationManager.AppSettings["MetaAuthor"];
			RuntimeSettings.MetaDescription = ConfigurationManager.AppSettings["MetaDescription"];
			RuntimeSettings.MetaKeywords = ConfigurationManager.AppSettings["MetaKeywords"];


			XmlConfigurator.Configure();

			AreaRegistration.RegisterAllAreas();

			this.RegisterGlobalFilters(GlobalFilters.Filters);
			this.RegisterRoutes(RouteTable.Routes);

			IWindsorContainer container = this.CreateContainer();

			IControllerFactory controllerFacotry = new WindsorControllerFactory(container.Kernel);
			ControllerBuilder.Current.SetControllerFactory(controllerFacotry);

			ModelBinders.Binders.Add(typeof(EntryEditViewModel), new WindsorModelBinder<EntryEditModelBinder>(container.Kernel));
			ModelBinders.Binders.Add(typeof(EntryEditAction), new WindsorModelBinder<EntryEditActionModelBinder>(container.Kernel));
			ModelBinders.Binders.Add(typeof(TagViewModel), new WindsorModelBinder<TagModelBinder>(container.Kernel));
			ModelBinders.Binders.Add(typeof(CommentViewModel), new WindsorModelBinder<CommentModelBinder>(container.Kernel));
			ModelBinders.Binders.Add(typeof(LoginViewModel), new WindsorModelBinder<LoginModelBinder>(container.Kernel));
			ModelBinders.Binders.Add(typeof(ResetPasswordViewModel), new WindsorModelBinder<ResetPasswordModelBinder>(container.Kernel));
			ModelBinders.Binders.Add(typeof(AdminSettingsViewModel), new WindsorModelBinder<AdminSettingsModelBinder>(container.Kernel));
			ModelBinders.Binders.Add(typeof(AuthorInfoViewModel), new WindsorModelBinder<AuthorInfoModelBinder>(container.Kernel));
			ModelBinders.Binders.Add(typeof(ContactViewModel), new WindsorModelBinder<ContactModelBinder>(container.Kernel));
		}

		protected void Application_BeginRequest(object sender, EventArgs e)
		{
			CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture;
			CultureInfo currentUICulture = Thread.CurrentThread.CurrentUICulture;

			try
			{
			   if (this.Context.Request.Cookies[Constants.Culture] == null)
			   {
					// set default culture
					CultureInfo defaultCulture = new CultureInfo("pl-PL");
					if (currentUICulture.Name.StartsWith("en"))
					{
						defaultCulture = new CultureInfo("en-US");
					}
					Thread.CurrentThread.CurrentCulture = defaultCulture;
					Thread.CurrentThread.CurrentUICulture = defaultCulture;
			   }
			   else
			   {
					// set previously selected culture saved in cookie
			      int cultureId = Convert.ToInt32(this.Context.Request.Cookies[Constants.Culture].Value);
			      CultureInfo selectedCulture = new CultureInfo(cultureId);
			      Thread.CurrentThread.CurrentCulture = selectedCulture;
			      Thread.CurrentThread.CurrentUICulture = selectedCulture;
			   }
			}
			catch (Exception)
			{
			   Thread.CurrentThread.CurrentCulture = currentCulture;
			   Thread.CurrentThread.CurrentUICulture = currentUICulture;
			}
		}

		public void RegisterGlobalFilters(GlobalFilterCollection filters)
		{
			filters.Add(new HandleErrorAttribute());
		}

		public void RegisterRoutes(RouteCollection routes)
		{
			routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

			routes.MapRoute
			(
				null,
				"{viewType}/Search/{searchValue}/{pageNumber}",
				new { controller = "Entries", action = "SearchList", pageNumber = 1 },
				new { pageNumber = @"\d+" }
			);

			routes.MapRoute
			(
				null,
				"{viewType}/Archive/{year}/{month}/{pageNumber}",
				new { controller = "Entries", action = "Archive", pageNumber = 1 },
				new { pageNumber = @"\d+", year = @"\d+", month = @"\d+", }
			);

			routes.MapRoute
			(
				null,
				"About",
				new { controller = "Entries", action = "About" }
			);

			routes.MapRoute
			(
				null,
				"",
				new { controller = "Entries", action = "List", viewType = MainViewType.Blog, pageNumber = 1, tag = (string)null },
				new { pageNumber = @"\d+" }
			);

			routes.MapRoute
			(
				null,
				"{viewType}/{pageNumber}",
				new { controller = "Entries", action = "List", tag = (string)null },
				new { pageNumber = @"\d+" }
			);

			routes.MapRoute
			(
				null,
				"{viewType}/tag{tag}/{pageNumber}",
				new { controller = "Entries", action = "List" },
				new { pageNumber = @"\d+" }
			);

			routes.MapRoute
			(
				null,
				"{viewType}/{action}/{entryId}",
				new { controller = "Entries" },
				new { entryId = @"\d+" }
			);

			routes.MapRoute
			(
				null,
				"{viewType}/New",
				new { controller = "Entries", action = "New" }
			);

			routes.MapRoute
			(
				 null,
				 "{controller}/{action}"
			);

			routes.MapRoute
			(
				null,
				"{controller}/{action}/{entryId}"
				, new { }
				, new { entryId = @"\d+" }
			);

			routes.MapRoute
			(
				null,
				"{controller}/{action}/{entryId}/{backAction}",
				new { },
				new { entryId = @"\d+" }
			);

			routes.MapRoute
			(
				 null,
				 "{controller}/{action}"
			);
		}

		private IWindsorContainer CreateContainer()
		{
			WindsorContainer container = new WindsorContainer();
			container.Install(Castle.Windsor.Installer.Configuration.FromAppConfig());
			container.Register(AllTypes.FromThisAssembly().BasedOn<IController>().Configure(c => c.LifeStyle.Transient));
			container.Register(AllTypes.FromThisAssembly().BasedOn<IModelBinder>().Configure(c => c.LifeStyle.PerWebRequest));
			container.Register(Component.For<IDatabaseContext>().UsingFactoryMethod((k, c) => k.Resolve<IDatabaseContextProvider>().CreateContext(this.GetUserName)).LifeStyle.PerWebRequest);

			return container;
		}

		private string GetUserName()
		{
			return Environment.UserName;
		}
	}
}